//����������� ���������� �������� - STL 
	//���������� ����������� ���������� - vector
	//���������

#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include "Header.h"
#include "myString.h"
#include "Point.h"

#pragma warning(disable: 4786)


using namespace std;	

#define	  stop __asm nop


int main()
{
	// ��������� ����������� ���������� vector 

//////////////////////////////////////////////////////////////////////
	//�������� ��������. 

	//�������� ��������� �������:
	//---------------------------
	//������ ������ ����� ����� - vInt � ��������� � ������� ������� size(),
	//��� ��� ������ �������. 
	vector<int> vInt;
	int n = vInt.size();
		
	//���������������� ��������� ��������, ��������� - ��� �� ���������
	//���� ���� ��������������, - ���������
	vInt.reserve(10);
	vInt.push_back(3);
	vInt.front()=1;//���� ������ ������, �� ������
	
	//� ������� ������� push_back() � ����� ��������� ������ ������-���� ����������.
	//�� ������ �������� ����� ������� �� �������� ������� � ������� �������
	//size(), capacity(), max_size() � �������� �������� ���������. 
	//
	//���������: ��� ��� ����� �������� ����������� ��� � � ��������� ��������,
	//�������� ������ �������, ������� ��� �������, ����������� �������� ������ ����
	//������� ��� "���������" � �������� ��������� �� �������.
	srand(time(NULL));

	for (int i = 0; i < 3; ++i)
	{
		vInt.push_back(rand()%20 + 1);
		tracking(vInt);
	}
	stop
	
	//������ ������������ - vDouble1 � �������� ���� ��������� ��������  �
	//��������� ��������� � ������� ���������� ���� �������. ��� �����
	//������������������� �������� �������?
	
	vector<double> vDouble1 (10);
	tracking(vDouble1);
	vDouble1.push_back(12.3);
	tracking(vDouble1);
	stop

	//������ �������� ���� MyString � ��������� �������� - 5 ���������
	//� �������������� ������� �������� ������� "A"
	//C ������� ������� at() � ����� � ������� ���������
	//�������������� []  �������� �������� �����-���� ���������.
	//���������� "�����" �� ������� ������� � ������� at() �
	//� ������� []. 

	vector<MyString> vString(5,MyString("A"));
	tracking(vString);

	vString.at(2).SetNewString("New");
	vString[0].SetNewString("First");
	tracking(vString);

	try
	{
		vString.at(7).SetNewString("Ups");
	}
	catch(std::out_of_range& err)
	{
		std::cerr << "Caught: " << err.what() << std::endl;
		std::cerr << "Type: " << typeid(err).name() << std::endl;
		std::cout << std::endl;
	}
	try
	{
		//vString[7].SetNewString("Ups");
	}
	catch (std::out_of_range& err)
	{
		std::cerr << "Caught: " << err.what() << std::endl;
		std::cerr << "Type: " << typeid(err).name() << std::endl;
		std::cout << std::endl;
	}

	stop

	//������ ������������ - vDouble3, ������� �������� ������ ���������
	// [0,5) ������� ������������ ����� dMas. �������������� ������ dMas 
	//����� ������� � �������������������!
	
	double dMas[]{1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};

	vector<double>vDouble3(dMas, dMas + 5);
	tracking(vDouble3);
	stop
	//������ ������������ - vDouble4, ������� �������� ������ ���������
	// [2,5) ������� vDouble3. 

	vector<double>vDouble4(vDouble3.begin()+2, vDouble3.end());
	tracking(vDouble4);
	stop

	//������ ��������� ���� Point - vPoint1 �) � ��������� �������� 3. ����� �����������
	//����� ������ ��� ������� ��������?
	//b) vPoint2 � ��������� �������� 5 � ������������������ ������ ������� ������������ (1,1).
	
	vector<Point>vPoint1(3);
	tracking(vPoint1);
	vector<Point>vPoint2(5,Point(1.,1.));
	tracking(vPoint2);
	stop

	//������ ���������� �� Point - vpPoint � ��������� �������� 5
	//���������: ��� ��������� ��������� ��� ��������� "���������" �� ������� Point
	{
	vector<Point*>vPoint(5);
	tracking(vPoint);

	for (int i = 0; i < 5; i++)
	{
		vPoint[i] = new Point(rand() % 10 + 1, rand() % 10 + 1);
	}
	tracking(vPoint);
	
	for (int i = 0; i < 5; i++)
	{
		delete vPoint[i];
	}

	stop
	//���������: ��� ������ �� ������ �������� ������ ����� ��� �����������
		//�) ������������� ����� ��������� �������
		//�) ��� ���������� operator<< ��� Point*

	}//����� �������������� �������� ����� ����������� ��� ������ �������?


	///////////////////////////////////////////////////////////////////////
	//�������������� ������.
	//���������, ������ �� ����� ����������� ���� ��������?
		
		{
		size_t n = 7;
		vector<int> v(n);
		v.resize(n/2);
		if (v.capacity() == n) { }//true?		
		}
		
			
		{
		int n = 11;
		size_t m = 7/*14*/;//��� m<n, �� ������ �� ����������
		vector<int> v(n);
		v.reserve(m);
		if (v.capacity() == m) { } //true?
		}
		
				
		{
		vector<int> v(3,5);
		v.resize(4,10); //��������? 5,5,5,10
		v.resize(5); //��������? 5,5,5,10,0
		}

	//�������� ��� "������" ������� � ����������
	//������ (�� ������ � ���� �� ����) ����. 
	//� ������ ������� �������������� ������ ��� 5 ���������, � ����� ���������
	//��� ���������� � ������� push_back.
	//������ ������ ������ ��������� ���������� ����������� push_back.
	//
	//�������� ������, ������� �������� � �������� ���������

	vector<int> vec1;
	vector<int> vec2;

	vec1.reserve(5);//����������� ��������������� �������, ����� ���� ����������� ����������������� ������

	for (size_t i = 0; i < 5; i++)
	{
		vec1.push_back(i+3);
		vec2.push_back(i+3);
	}

	tracking(vec1);//size:5,capacity:5
	tracking(vec2);//size:5,capacity:6 

	//!!! shrink_to_fit - ���������� ������� �������.
	//��� ������ ������� �� ����������� ������� ��������� ��������� �������
	//�� size.

	vec2.shrink_to_fit();
	tracking(vec2); //size:5,capacity:5

	//�������� "����������� �������" - ������� ��������
	//����� ���������� ������ int ar[] = {11,2,4,3,5};
	//�������� ������ �������� ��������� �������:
	//������ vv[0] - �������� 11 ��������� �� ��������� 11
	//vv[1] - �������� 2,2
	//vv[2] - �������� 4,4,4,4
	//...
	//������������ ���������� ������ ����������� ������� �� �������
	//� �������:
	//std::cout << vv1 << std::endl;

	int ar[] = { 11,2,4,3,5 };
	vector<vector<int>> vv1;
	vv1.resize(sizeof(ar) / sizeof(int));

	for (int i = 0; i < sizeof(ar) / sizeof(int); i++)
	{
		int j = ar[i];
		vv1[i].resize(j,j);			
	}
	
	std::cout<<vv1<<std::endl;
	 stop

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	//������� �������� ������������������ insert().
	//���������� �������, ������� ������ ��������� ����� �������
		//� ������ ������� ������ ��� �������, ��� � ������� ������
		 //�������� ��� ���.
	//��������� ����������������� ������� - � ������ vChar2 �������� � ������ ������� ������ ������ ���
	//�������, ��� � ������� ������ ������� ��� ���.
		 //��������: vChar2 - abc 
		 //��� ������� �������� 'a' ������� ������ ���� ���������������
		 //��� ������� �������� 'q' vChar2 - qabc 

	vector<char>vChar2 = { 'a', 'b', 'c' };
	
	insert_if_not(vChar2, 'a');
	insert_if_not(vChar2, 'q');
	tracking(vChar2);
	stop
	//���������� �������, ������� ������ ��������� ����� �������
	//����� ������ ��������� �������
	//��������� ����������������� ������� - �������� ����� ������ ��������� ������� vChar2 ����� 'W'
	
	insert_between(vChar2,'W');
	tracking(vChar2);

///////////////////////////////////////////////////////////////////
	//�������� �������, ������� ������ ������� ������ ������������� ������������������.
	//��������: ���� - "qwerrrrty12222r3", ����� - "qwety1r3"
//not unique
//erase 
//��� �������� �������� ������
	char Str[] = "qqwerrrrty12222r33";// ������� ��� ������� � ������ ��� � �����!!!!
	vector<char> vChar(Str, Str + (sizeof(Str)/sizeof(Str[0]))-1);
	tracking(vChar);
	delete_repeated(vChar);
	tracking(vChar);
	stop
///////////////////////////////////////////////////////////////////

	//�������� �������� ������������������ erase()
	//�������� ������� �������� �� ������ ������� ���� ������ 
		 //��������: ���� - "qwerrrrty12222r3", ����� - "qwerty123"
//not unique
//erase 2�����
//��� �������� �������� ������
	
	vChar.assign(Str, Str + (sizeof(Str) / sizeof(Str[0])) - 1);
	tracking(vChar);
	delete_dublicate(vChar);
	tracking(vChar);
	stop
///////////////////////////////////////////////////////////////////
	//�������� ����� ������ ����� �������, ����� ��� �������� �����
	//������� ��������� ������ �� ��������� ����� ��������, �� �����������
	//���� �� � �������� �������

	vector<char> r_vChar(vChar.rbegin(), vChar.rend());
	tracking(r_vChar);
	stop

///////////////////////////////////////////////////////////////////

	//������� 1. ������. ��������, ����������� ��� �������.
	//�������� ������ ������ �� ��������� Point - ptList1 � ���������
	//��� ���������� � ������� ������� push_back(),
	//push_front, insert()
	
	list<Point> ptList1;
	ptList1.push_front(Point(1,1));
	ptList1.push_back(Point(3, 3));
	ptList1.insert(++ptList1.begin(), Point(2, 2));
	
	list<Point>::iterator Ib = ptList1.begin(), Ie = ptList1.end();

	while (Ib != Ie)
	{
		cout << *Ib << " ";
		++Ib;
	}
	cout << endl;


	//�������� ������ �������, ������� ����� �������� ��������
	//������ ���������� �� ������. ��������� ������ ������� �� �����������
	//vector � list. ��������� - �������� �� ������� ��� ����������.
	print(ptList1);
	print(vec1);
	
	
	//�������� ����� �� ������� "�����������" - reverse()
	
	ptList1.reverse();
	print(ptList1);
	
	//�������� ������ ptList2 �� ��������� Point ����� �������, ����� �� ���� 
	//������ ������� ��������� ���� Point, �� �������� ��������� ������ �������������
	//�� � �������� ������� 

	vector<Point> vP;
	vP.reserve(10);
	for (int i = 0; i < 7; i++)
	{
		vP.push_back(Point(rand()% 10 +1, rand() % 10 + 1));
	}
	print(vP);
	list<Point> ptList2(vP.rbegin(), vP.rend());
	print(ptList2);
	

	//������������ ������  ptList1 � ptList2 - ������� ������ list - sort()
	//�� �����������.
	//���������: ��� ������ ���� ����������� � ������ Point ��� ����, �����
	//�������� ����������
	print(ptList1);
	ptList1.sort();
	print(ptList1);

	print(ptList2);
	ptList2.sort();
	print(ptList2);
	
	stop

	//���������� ��������������� ������ - merge(). ����������: ���
	//��� ���� ���������� � ������ �������.
	ptList1.merge(ptList2); // ptList2- size =0; 
	print(ptList1);
	print(ptList2);
	stop

	//���������� �������� �� ������ - remove()
	//��������� �� ������ ������� � ������������ ���������.
	//���������: ��� ������ ���� ����������� � ������ Point?
	ptList1.remove(Point(1, 1));
	print(ptList1);
	stop
	//���������� �������� �� ������, ���������������� ��������� �������:
	//����� �� ��������� ������������ - remove_if(). 
	ptList1.push_front(Point(-3,7));
	ptList1.push_back(Point(7, -3));
	print(ptList1);
	ptList1.remove_if(&Negative);
	print(ptList1);

	//���������� �� ������ ������ ������������� ������ - unique(). 
	
	ptList1.push_front(ptList1.front());
	ptList1.push_front(ptList1.front());
	ptList1.push_front(ptList1.front());
	print(ptList1);
	ptList1.unique();
	print(ptList1);
	stop

///////////////////////////////////////////////////////////////////
	//������� 2.������� � ����� ������� - ��������� deque

	//�������� ������ deque � ���������� ���� Point. � �������
	//assign ��������� deque ������� ��������� �������. � �������
	//�������������� ���� � ���������� ������� �������������� �������
	//�������� �������� ��������� �� ������
	deque<Point> d_pt;
	d_pt.assign(vP.rbegin(), vP.rend());
	print(d_pt);
	stop

	//�������� deque � ���������� ���� MyString. ��������� ��� ����������
	//� ������� push_back(), push_front(), insert()
	//� ������� erase ������� �� deque ��� ��������, � ������� �������
	//���������� � 'A' ��� 'a'
	deque<MyString> d_ms;
	d_ms.push_back(MyString("ffff"));
	d_ms.push_back(MyString("afff"));
	d_ms.push_back(MyString("AAff"));
	d_ms.push_front(MyString("zzzzz"));
	d_ms.push_front(MyString("rrrrr5"));
	d_ms.push_front(MyString("ppppp"));
	
	deque<MyString>::const_iterator It_b = d_ms.begin();
	++It_b;
	++It_b;
	d_ms.insert(It_b, MyString("aaff"));
	print(d_ms);
	
	{
	deque<MyString>::const_iterator It_b = d_ms.begin(), It_e = d_ms.end();
	//int k = d_ms.size();
	while(It_b!= d_ms.end())
	{
		char simb = *(*It_b).GetString();
		if (simb == 'a' || simb == 'A') { It_b = d_ms.erase(It_b);}	
		else { ++It_b; }
	}
	print(d_ms);
	}
	stop
	return 0;
}